package com.example.demo.config;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.example.demo.jwt.JwtToken;
import com.example.demo.jwt.JwtUtils;
import com.example.demo.mapper.UserMapper;

/**
 * 安全领域，配置一个身份验证，权限验证
 * 
 * @author Administrator
 *
 */
@Component
public class RealmConfig extends AuthorizingRealm {

	@Autowired
	private UserMapper userMapper;

	/**
	 * 必须重写此方法，不然会报错
	 */
	@Override
	public boolean supports(AuthenticationToken token) {
		return token instanceof JwtToken;
	}

	/**
	 * 获取身份验证信息 Shiro中，最终是通过 Realm 来获取应用程序中的用户、角色及权限信息的。
	 *
	 * @param authenticationToken 用户身份信息 token
	 * @return 返回封装了用户信息的 AuthenticationInfo 实例
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
			throws AuthenticationException {

		System.out.println("————身份认证方法————");

		String token = (String) authenticationToken.getCredentials();
		/**
		 * 在这里进行jwt获取用户进行验证
		 */
		// 解密获得username，用于和数据库进行对比
		String username = JwtUtils.getUsername(token);

		if (username == null || !JwtUtils.verify(token, username)) {
			throw new AuthenticationException("token认证失败！");
		}
		String password = userMapper.getPassword(username);
		if (password == null) {
			throw new AuthenticationException("该用户不存在！");
		}
		// 主要的信息，证书，名字
		return new SimpleAuthenticationInfo(token, token, "MyRealm");
	}

	/**
	 * 获取授权信息
	 *
	 * @param principalCollection
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String username = JwtUtils.getUsername(principals.toString());
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		
		// 获得该用户角色
		String role = userMapper.getRole(username);
		// 每个角色拥有默认的权限
		// String rolePermission = userMapper.getRolePermission(username);
		// 每个用户可以设置新的权限
		// String permission = userMapper.getPermission(username);
		
		Set<String> roleSet = new HashSet<>();
		Set<String> permissionSet = new HashSet<>();
		
		// 需要将 role, permission 封装到 Set 作为 info.setRoles(), info.setStringPermissions()
		// 的参数
		roleSet.add(role);
		// permissionSet.add(rolePermission);
		// permissionSet.add(permission);
		// 设置该用户拥有的角色和权限
		info.setRoles(roleSet);
		info.setStringPermissions(permissionSet);
		
		return info;
	}
}
